Stepper 通過編號的步驟傳達進度,它提供了類似嚮導的工作流程。
他除了有前面提到的 Tabs 的屬性外還有提供紀錄進度的功能,可以通過將當前步進索引(從零開始)作為 activeStep 屬性傳遞來控制步進器,Stepper方向是使用 orientation 屬性設置的,所以如果要調整成垂直的狀態只要設置成 orientation="vertical",alternativeLabel 屬性則可以讓標籤的位置改再 icon 之下。
// 先設置step title
function getSteps() {
return ['基本資料', '選擇商品型號', '配送資訊'];
}
// 再設置step content,可以用其他組件來替換
function getStepContent(stepIndex) {
switch (stepIndex) {
case 0:
return '基本資料頁面...';
case 1:
return '選擇商品型號頁面...';
case 2:
return '配送資訊...';
default:
return 'step 未設定';
}
}
// in export function
const [activeStep, setActiveStep] = React.useState(0);
const steps = getSteps();
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleReset = () => {
setActiveStep(0);
};
/*in return*/
<div className={classes.root}>
<Stepper activeStep={activeStep} alternativeLabel>
{steps.map((label) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>填寫完畢</Typography>
<Button onClick={handleReset}>重置</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.backButton}
>
上一步
</Button>
<Button variant="contained" color="primary" onClick={handleNext}>
{activeStep === steps.length - 1 ? '完成' : '下一步'}
</Button>
</div>
</div>
)}
</div>
</div>
官網文件上有提供Skip的範例做法:
// ...前面的段落一樣
// in export function
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set());
const isStepOptional = (step) => {
return step === 1;
};
const isStepSkipped = (step) => {
return skipped.has(step);
};
const handleNext = () => {
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// 需要防範此情形,一般的使用情境下不太容易發生
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped((prevSkipped) => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const handleReset = () => {
setActiveStep(0);
};
<div className={classes.root}>
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (isStepOptional(index)) {
labelProps.optional =
<Typography variant="caption">
Optional
</Typography>;
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you're finished
</Typography>
<Button onClick={handleReset} className={classes.button}>
Reset
</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>
{getStepContent(activeStep)}
</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.button}
>
Back
</Button>
{isStepOptional(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
可以依照實際的情況去修改邏輯,這個作法不是固定的。
設定 nonLinear 屬性,可以讓進程的線不亮。
<Stepper activeStep={activeStep} nonLinear alternativeLabel>
{steps.map((label) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
另外還有類似 Carousel 的範例在官方的文件上,這裡我就不再贅述他的用法了,因為我相信通常在處理這種 lightbox 的東西會去用類似 splidejs 這種專門的套件,可能會比較方便一些。
那麼今天的內容就到這裡了,明天會講解 Menu 組件的用法。